package com.jarveis.dbs.core;

import java.util.Iterator;
import java.util.List;

import org.apache.log4j.Logger;

import com.jarveis.dbs.core.bean.FilterBean;
import com.jarveis.dbs.core.filter.Filter;
import com.jarveis.dbs.core.filter.FilterProxy;
import com.jarveis.frame.util.Param;

/**
 * 数据访问入口
 * 
 * @author liuguojun
 * @date 2014-06-05
 */
public class DBServiceImpl implements DBService {

	private static final long serialVersionUID = 6741206647119024131L;

	private static final Logger logger = Logger.getLogger(DBServiceImpl.class);

	/**
	 * 处理请求
	 * <pre>
	 * _message = {
	 * 	head:{
	 * 		appId: '客户端标识',
	 * 		appVerion: '版本号',
	 * 		token: '服务器编码',
	 * 		device: '设备编码',
	 * 		funcId: '功能编码',
	 * 		dataType: '数据类型'
	 * 	}
	 * 	body:{
	 * 		name: 'Tom' // 功能所需参数
	 * 	}
	 * }
	 * </pre>
	 * 
	 * @param message
	 *            请求消息
	 * @throws Exception
	 */
	public String process(String message) throws Exception {
		// 获取请求对象
		Param in = getReqParam(message);
		String dataType = in.getHead().getString(Param.LABEL_DATATYPE);

		int errCode = filter("before", in);
		if (errCode > 0) {
			return reResponse(dataType, errCode);
		}

		String funcId = in.getHead().getString(Param.LABEL_FUNCID);
		Param out = ServiceProxy.callService(funcId, in);

		errCode = filter("after", out);
		if (errCode > 0) {
			return reResponse(dataType, errCode);
		}

		return reResponse(out);
	}

	/**
	 * 获取请求对象
	 * 
	 * @param message
	 *            请求消息
	 * @return Param
	 * @see com.jarvice.frame.util.Param
	 */
	private Param getReqParam(String message) {
		Param in = null;

		try {
			in = new Param(message);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}

		return in;
	}

	/**
	 * 返回消息
	 * 
	 * @param dataType
	 *            数据类型
	 * @param errCode
	 *            错误编码
	 */
	private String reResponse(String dataType, int errCode) {

		try {
			Param out = new Param("Resp");
			out.getHead().setProperty(Param.LABEL_DATATYPE, dataType);
			out.getHead().setProperty(Param.LABEL_ERROR, errCode);
			logger.info(out.toString());

			return reResponse(out);
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}

		return null;
	}

	/**
	 * 返回消息
	 * 
	 * @param out
	 *            输出对象
	 */
	private String reResponse(Param out) {

		try {
			return out.toString();
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}

		return null;
	}

	/**
	 * 过滤器
	 * 
	 * @param filterType
	 *            过滤器类型
	 * @param param
	 *            参数对象
	 * @return
	 */
	private int filter(String filterType, Param param) {
		int errCode = Param.ERROR_EXCEPTION;

		try {
			// 功能编码
			String funcId = param.getHead().getString(Param.LABEL_FUNCID);

			List<FilterBean> filters = DBContext.getInstance().getFilters();
			for (Iterator<FilterBean> it = filters.iterator(); it.hasNext();) {
				FilterBean filterBean = it.next();
				String id = filterBean.getId(); // 过滤器编码
				String type = filterBean.getType(); // 过滤器类型
				String match = filterBean.getMatch(); // 匹配算法（正则）

				if (!filterType.equals(type)) {
					continue;
				}

				if (!funcId.matches(match)) {
					continue;
				}

				Filter filter = FilterFactory.get(id);
				if (filter == null) {
					continue;
				}

				errCode = FilterProxy.callFilter(filter, param);
				if (errCode != 0) {
					break;
				}
			}
		} catch (Exception ex) {
			logger.error(ex.getMessage(), ex);
		}

		return errCode;
	}

}
